home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fritz: All Fritz
/
All Fritz.zip
/
All Fritz
/
FILES
/
UTILFILE
/
OPTIM.LZH
/
OPTIM.ASM
next >
Wrap
Assembly Source File
|
1987-04-13
|
24KB
|
1,163 lines
NAME OPTIM
.XLIST
PAGE 105,132
TITLE Fixed Disk Optimising Program
.LIST
COMMENT *
Uses High resolution Timer routine to check speed of processes.
*
;---------------------
; MACROS
;---------------------
DISPLAY MACRO ; Display String @ DS:DX
MOV AH,9
INT 21H
ENDM
HEADSET MACRO
MOV DL,CS:[DR_ID]
MOV DH,0
MOV CX,01H
MOV AX,21AH
MOV BX,OFFSET DTABUF
INT 13H
ENDM
;------------------
; EQUATES
;------------------
TIM_LOW EQU 006CH ; Location of System Clock
BIOS_DSEG EQU 0040H ; Address of BIOS Data segment
TIM_MODE EQU 43H ; Control Port Address of 8253-5 chip
TIM_0 EQU 40H ; Read Port Address of 8253-5
;------------------
; CODE
;------------------
ASSUME CS:CODE, DS:CODE
CODE SEGMENT
MAIN PROC NEAR
ORG 100H
BEGIN: JMP START
COUNT DW 0 ; Interrupt Ticks 54.925 msecs
COUNT_MICRO DW 0 ; Calculate from COUNT
COUNT_MILLI DW 0 ; Calculate from COUNT
TIM_MICRO DW 0 ; From 8253 counter
TIM_MILLI DW 0 ; Final Value
TIM_SEC DW 0 ; Final Value
TIM1MIC DW 0 ; Test 1 Microseconds
TIM1MIL DW 0 ; Test 1 Milliseconds
TIM1SEC DW 0 ; Test 1 Seconds
TIM2MIC DW 0 ; Test 2 Microseconds
TIM2MIL DW 0 ; Test 2 Milliseconds
TIM2SEC DW 0 ; Test 2 Seconds
TIM3MIC DW 0 ; Test 3 Microseconds
TIM3MIL DW 0 ; Test 3 Milliseconds
TIM3SEC DW 0 ; Test 3 Seconds
TIM4MIC DW 0 ; Test 4 Microseconds
TIM4MIL DW 0 ; Test 4 Milliseconds
TIM4SEC DW 0 ; Test 4 Seconds
COUNT_MAX DW 65535 ; Starting point
ADJUSTM DW 0 ; Compensating Factor
TIM_CONV DW 8381 ; 838.096 nsec/tick
COUNT_CONV DW 54925 ; 54.925 msec/tick
TEN_TH DW 10000 ; Divisor 1
FIVE_TH DW 5000 ; Divisor 2
THOU DW 1000 ; Divisor 3
TEN DW 10 ; Divisor 4
INTERLEAVE DB 16 ; Interleave Count
INTLVE DB 0 ; Optimum Interleave
LOWMIC DW 0FFFFH
LOWMIL DW 0FFFFH
LOWSEC DW 0FFFFH
ANSYN DB 'YYN',13
ANSCD DB 'CCD',13
DR_ID DB 80H
;-------------------
; Message Area
;-------------------
SIGN_ON DB '╔══════════════════════════════════════════════════════════════════════════════╗',13
DB '║ CUMANA - Fixed Disk Installation and Optimisation - Version 1.20 ║',13
DB '║ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ║',13
DB '║ ║',13
DB '║ This Program is designed to set up a Fixed Disk Unit from scratch. ║',13
DB '║ ║',13
DB '║ Once you have elected to continue, the program will list the settings of ║',13
DB '║ the selected drive. If you accept these settings as correct, the ║',13
DB '║ program will then experimentally format Cylinders 0 and 1 and time the ║',13
DB '║ access for each of 16 interleave values. Once this process has ended, ║',13
DB '║ the whole disk will be formatted at the optimum interleave setting. ║',13
DB '║ This ensures that Fixed Disk performance will be efficiently matched to ║',13
DB '║ your machine. ║',13
DB '║ ║',13
DB '║ When formatting has been completed, you will be asked to enter details ║',13
DB '║ of defective areas of the disk. These are usually written on the disk ║',13
DB '║ itself or the relevant documentation. Make a note of the Cylinders and ║',13
DB '║ Heads involved BEFORE you run the program, so that you don',39,'t need to ║',13
DB '║ move the disk while it is in operation. Cylinder numbers should be ║',13
DB '║ entered in decimal notation. UpoN τorre"t C-p,%tdäüâƒΘ>╔┤ôIiê&a7nM╙Süñß≥$" ü$*eÅFsW7N&`@êy≡0q ≤0É@ ±└9≡0q ±Ç 0@ ≡ @0y≡Ç0└æ ≡@Ç1└01└0@ α8╚ÄNC3₧I ∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙α8╚ÄNC3₧I ∙≡≡æ Çë±╔≥ I≡ q ≡@ ±└æ ≡æ┴0I≡0 ±Ç 0@ °∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙αs ║',13
DB '╚══════════════════════════════════════════════════════════════════════════════╝',13,'$'
MESS_01 DB 'WARNING !!! This program will ERASE all data on the selected drive!',13,10
DB '║ Do you want to continue? [N]$'
MESS_AVE DB ' $'
MESS_SEC DB ' Seconds$'
MESS_MIL DB '.$'
MESS_MIC DB ' $'
MESS_RUN DB 'Interleave '
MESS_EQ DB ' timed at $'
ASC_STR DB 5 DUP('d'),'$'
BLANKLINE DB ' $'
LF DB 13,10,'║ $'
BELL DB 7,'$'
MESS_OPT0 DB 'Optimising Interleave - $'
MESS_OPT1 DB 'Optimum Interleave is '
MESS_OPT2 DB ' ',13,10,'║ $'
MESS_OPT3 DB ' FORMATTING DRIVE '
MESS_OPT4 DB 'C'
DB ' with Interleave $'
MESS_OPT5 DB 'Any Bad Tracks to Enter? [N]$'
MESS_OPT6 DB 'Enter Cylinder Number (Decimal) ... $'
MESS_OPT7 DB 'Enter Head Number ................ $'
MESS_OPT8 DB 'Bad Track Flagged! Any more Bad Tracks? [N]$'
MESS_OPT9 DB 'Format Completed ',13,10,10,'║ $'
MESS_OPT10 DB 'Entering Bad Track information ... ',13,10,'$'
DUFF_CONT DB 'DISK CONTROLLER ERROR REPORTED!',13,10
DB 'Please check Controller Cables and Connections.',13,10,'$'
LOG_PART DB 'The Controller indicates that the Drive is set for LOGICAL PARTIONING ',13,10
DB '║ This program cannot handle Logical Formatting - please us the ROM routine.',13,10,10,'$'
SELECT1 DB 'Select Drive to Format (C or D) [C]$'
DR_REPP DB 'Selected Drive has these Settings ...',13,10,10
DB '║ $'
DR_CYL DB ' Number of CYLINDERS ... : $'
DR_HDS DB ' Number of HEADS ....... : $'
CYLS DW 00
HDS DB 0
ABORT DB 13,10,'║ Returning to Operating System ...',13,10,'$'
CONTINUE DB 13,10,'║ Writing Partition Table ...'
DB 13,10,'║ Rebooting to establish Drive'
DB 10,10,10,10,10,10,10,10,13,'$'
CONFIRM DB 'Are these correct? [Y]$'
BADCYL DB 13,10,'║ Invalid Cylinder Number!$'
BADHD DB 13,10,'║ Invalid Head Number!$'
DB 'Author Jim Bates - BATES Associates'
ASSUME CS:CODE, DS:CODE, ES:CODE
SET_BADTRAK:
MOV DH,AL
MOV DL,BYTE PTR CS:[DR_ID]
XCHG BH,BL
MOV CX,6
SHL BL,CL
ADD BX,1
MOV CX,BX
MOV AX,601H
INT 13H
RET
GETNUM:
mov cl,30H
mov ch,cl
mov dx,cx
mov bl,0
GETNUM00:
mov ah,1
int 21H
cmp al,0DH
jnz GETNUM01
cmp bl,0
jnz GETNUM07
mov ch,2
ret
GETNUM01:
cmp al,8
jz GETNUM05
inc bl
cmp bl,4
ja GETNUM02
mov dh,dl
mov dl,ch
mov ch,cl
mov cl,al
jmp GETNUM00
GETNUM02:
mov bh,0
GETNUM03:
mov dl,8
mov ah,2
int 21H
dec bl
cmp bl,0
jnz GETNUM03
cmp bh,1
jz GETNUM
GETNUM04:
mov dl,20H
mov ah,2
int 21H
inc bl
cmp bl,4
jbe GETNUM04
inc bh
jmp GETNUM03
GETNUM05:
push dx
mov dl,20H
mov ah,2
int 21H
cmp bl,0
jz GETNUM06
mov dl,8
mov ah,2
int 21H
pop dx
mov cl,ch
mov ch,dl
mov dl,dh
mov dh,30 ;"0"
dec bl
jmp GETNUM00
GETNUM06:
pop dx
jmp GETNUM00
GETNUM07:
mov bl,0AH
mov al,39H
cmp cl,al
jg GETNUM08
cmp ch,al
jg GETNUM08
cmp dl,al
jg GETNUM08
cmp dh,al
jg GETNUM08
mov al,30H
sub cl,al
jc GETNUM08
sub ch,al
jc GETNUM08
sub dl,al
jc GETNUM08
sub dh,al
jc GETNUM08
mov al,dh
mov ah,0
mul bl
mov dh,0
add ax,dx
mul bl
mov dl,ch
add ax,dx
mul bl
mov dl,cl
add ax,dx
mov ch,0
ret
GETNUM08:
mov ch,2
ret
PRTDX: PUSH DS
MOV AX,CS
MOV DS,AX
DISPLAY
POP DS
RET
RINGBELL:
MOV DX,OFFSET [BELL]
CALL PRTDX
RET
BACK2:
PUSH AX
PUSH BX
PUSH DX
PUSH SI
MOV BH,0
MOV AH,3 ; Get Cursor into DX
INT 10H
SUB DL,2
MOV AH,2 ; Set Cursor from DX
INT 10H
POP SI
POP DX
POP BX
POP AX
RET
GETANS: ; Set DI to point to required ANS string
PUSH ES
PUSH SI
PUSH BX
PUSH CX
PUSH DX
CLD
PUSH CS
POP ES
PUSH DI
G1:
POP DI
PUSH DI
MOV AH,8
INT 21H
AND AL,0DFH ; Convert to Upper Case
MOV CX,4
REPNZ SCASB
JNZ G1
CMP AL,0DH
JZ G2
MOV BH,0
MOV CX,1
MOV AH,0AH ; Show Character
INT 10H
JMP G1
G2:
POP DI
MOV BH,0
MOV AH,8 ; Get Character at Cursor
INT 10H
PUSH AX
CALL GETCURS
INC DH
MOV DL,2
CALL SETCURS ; to Next Line col 3
POP AX
POP DX
POP CX
POP BX
POP SI
POP ES
RET
GETCHARE:
MOV AH,1
INT 21H
RET
GETCHAR:
MOV AH,8
INT 21H
RET
GETCURS:
PUSH CX
PUSH AX
PUSH BX
PUSH SI
MOV AH,3
MOV BH,0
INT 10H
POP SI
POP BX
POP AX
POP CX
RET
SETCURS:
PUSH AX
PUSH BX
PUSH CX
PUSH SI
MOV AH,2
MOV BH,0
INT 10H
POP SI
POP CX
POP BX
POP AX
RET
GET_STATUS:
PUSH AX
PUSH DX
CALL GET_PORT_OFFSET
IN AL,DX
AND AL,80H
CMP AL,80H
POP DX
POP AX
RET
GET_PORT_OFFSET:
PUSH BX
MOV BX,77H
MOV BL,BYTE PTR [BX]
XOR BH,BH
MOV DX,322H
ADD DX,BX
POP BX
RET
HEX2ASC:
push bx
push cx
push dx
push si
mov bx,42H
mov WORD PTR [bx],2020H
mov WORD PTR [bx+02],2020H
mov WORD PTR [bx+04],2020H
mov bx,4
mov cx,0AH
CLRS1:
xor dx,dx
div cx
add dl,30H ;"0"
mov si,42H
mov [bx+si],dl
dec bx
cmp ax,0
jnz CLRS1
pop si
pop dx
pop cx
pop bx
ret
SET_STAT:
push ax
push dx
push es
call GET_PORT_OFFSET
in al,dx
call GET_STATUS
jc STST
push bx
mov bx,43H
mov ah,[bx]
pop bx
and ah,20
jz STST
mov cl,4
shr al,cl
STST:
mov cl,4
and al,7
shl al,cl
xor ah,ah
push ax
push ds
push es
push ax
mov ax,0
mov ds,ax
pop ax
mov bx,104H
push ax
mov ax,0
mov es,ax
pop ax
mov bx,es:[bx]
pop es
pop ds
pop ax
add bx,ax
pop es
pop dx
pop ax
ret
SETBLANK:
mov si,42H
mov cx,5
STB1:
mov al,[si]
cmp al,20H ;" "
jnz STB2
inc si
dec cx
jmp STB1
STB2:
ret
SHOWNUM:
MOV DL,[SI]
MOV AH,2
INT 21H
INC SI
LOOP SHOWNUM
RET
;###
TIM_START: ; Start Clock
PUSH AX
PUSH DX
PUSH DS
MOV TIM_MICRO,0 ; Clear area for final results
MOV TIM_MILLI,0 ;
MOV TIM_SEC,0 ;
;Initialise counter 0 of 8253 chip
MOV AL,00110100B ; Set mode for Counter 0
CLI
OUT TIM_MODE,AL
SUB AX,AX ; Set Counter at Zero
OUT TIM_0,AL ; LSB
OUT TIM_0,AL ; MSB
MOV DX,BIOS_DSEG ; Read current setting of System Clock
MOV DS,DX
MOV AX,DS:[TIM_LOW]
STI
POP DS
MOV COUNT,AX ; Save it
POP DX ; Restore Registers
POP AX
RET
; Elapsed timer since Timer start =
; 1) Timer count ticks @ 840 nSecs
; 2) Interrupt ticks @ 54 mSecs
TIM_STOP: ; Stop Clock
PUSH AX
PUSH BX
PUSH DX
MOV AL,0 ; Ready to read 8253
CLI ; Interrupts off until system clock read
OUT TIM_MODE,AL ; Set Mode for read
IN AL,TIM_0 ; Read LSB
MOV DL,AL ; Save it
IN AL,TIM_0 ; Read MSB
MOV DH,AL ; Save it
MOV AX,COUNT_MAX
SUB AX,DX ; Timer Count Value
MUL TIM_CONV ; Make to tenths of a nanosecond
DIV TEN_TH ; Make to microseconds
MOV TIM_MICRO,AX ; Save it
CMP DX,FIVE_TH ; Round nanoseconds
JB CONT ; Round down
INC TIM_MICRO ; Round up
CONT: MOV DX,BIOS_DSEG
MOV DS,DX
MOV AX,DS:[TIM_LOW] ; Collect System Clock reading
PUSH CS
POP DX
MOV DS,DX ; Restore DS register
SUB AX,COUNT ; System ticks since start
MUL COUNT_CONV ; Make to thousandths of millisecond
DIV THOU ; Make to milliseconds
MOV COUNT_MILLI,AX ; Save millisecs
MOV COUNT_MICRO,DX ; Save microsecs
CMP AX,0 ; Check for elapsed time less than 1 mSec
JNE JIT ; If not - no problem
MOV AX,ADJUSTM ; Compensation amount
CMP TIM_MICRO,AX ; Less than microseconds?
JAE JIT ; No - so OK
MOV TIM_MICRO,AX ; Yes so use compensation
JIT: MOV AX,DX ; This is System Microsecs
ADD AX,TIM_MICRO ; Add Timer Microsecs
CMP AX,ADJUSTM ; any underflow?
JAE COMP ; No - so continue
DEC COUNT_MILLI ; Yes - so borrow
ADD AX,1000
COMP: SUB AX,ADJUSTM ; Apply compensation
MOV TIM_MICRO,AX
CMP AX,1000 ; any overflow?
JB FLDOK ; No - so continue
SUB DX,DX ; TIM_MICRO too large!
DIV THOU ; so carry into TIM_MILLI
MOV TIM_MILLI,AX
MOV TIM_MICRO,DX
FLDOK: MOV AX,COUNT_MILLI ; Get System milliseconds
ADD TIM_MILLI,AX ; Add to timer milliseconds
CMP TIM_MILLI,1000 ; any overflow
JB QUIT ; No - so continue
SUB DX,DX ;
MOV AX,TIM_MILLI ; TIM_MILLI too large
DIV THOU ; so carry into TIM_SEC
MOV TIM_SEC,AX ; Save Seconds
MOV TIM_MILLI,DX ; Save Milliseconds
QUIT:
POP DX ; Restore registers
POP BX
POP AX
RET
;----------------------------------
; Decode and Display Time readings
;----------------------------------
SHOW_AVE:
PUSH AX
PUSH BX
PUSH DX
LEA DX,MESS_AVE
JMP SHOW0
SHOW:
PUSH AX ; Save registers
PUSH BX
PUSH DX
LEA DX,MESS_RUN ; Display Seconds Message
SHOW0: CALL PRTDX
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_SEC ; Get Value of Seconds
CALL BIN2ASC ; Convert from binary to ASCII
MOV DX,BX ; Transfer pointer
CALL PRTDX ; Display Seconds value
LEA DX,MESS_MIL ; Display Decimal point
CALL PRTDX
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_MILLI ; Get Value of Milliseconds
CALL BIN2ASC ; Convert from binary to ASCII
LEA DX,ASC_STR+2 ; Point to last three digits
CALL PRTDX ; Display Milliseconds Value
LEA DX,MESS_MIC ; Display comma
CALL PRTDX
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_MICRO ; Get Value of Microseconds
CALL BIN2ASC ; Convert from binary to ASCII
LEA DX,ASC_STR+2 ; Point to last three digits
CALL PRTDX ; Display Microseconds value
LEA DX,MESS_SEC
CALL PRTDX
POP DX ; Restore registers
POP BX
POP AX
RET
;--------------------------------------------
; Binary to ASCII conversion into ASC_STR
;--------------------------------------------
; Value to be converted is passed in AX and written to ASC_STR
BIN2ASC:
PUSH DX ; Save registers
PUSH CX
PUSH AX
MOV CX,5 ; Clear ASC_STR
CLBUF: MOV BYTE PTR [BX],30H ; Put zeroes in
INC BX
LOOP CLBUF
CONV: SUB DX,DX ; Clear upper half of dividend
DIV TEN ; = (DX:AX)/10
ADD DX,30H ; Convert to ASCII
DEC BX ; bump pointer
MOV [BX],DL ; Save digit
OR AX,AX ; Check if finished?
JNZ CONV ; No - go again!
POP AX ; Restore registers
POP CX
POP DX
RET
;------------------------
; CONVERT TIME TO ASCII
;-----------------------
TIM2ASC:
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_SEC ; Get Value of Seconds
CALL BIN2ASC ; Convert from binary to ASCII
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_MILLI ; Get Value of Milliseconds
CALL BIN2ASC ; Convert from binary to ASCII
LEA BX,ASC_STR ; Point to ASC_STR area
MOV AX,TIM_MICRO ; Get Value of Microseconds
CALL BIN2ASC ; Convert from binary to ASCII
RET
;------------------------
; MAIN CODE XXXXX
;------------------------
START:
MOV AX,600H
MOV CX,0
MOV DX,184FH
MOV BH,1FH
INT 10H
MOV DX,0
CALL SETCURS
LEA DX,SIGN_ON ; Display Sign-on Message
CALL PRTDX ; Prints frame
MOV AH,01
INT 21H
MOV AX,600H
MOV CX,0302H
MOV DX,164DH
MOV BH,1FH
INT 10H
MOV AX,40H
MOV DS,AX
MOV AX,0 ; Reset Fixed Drive 1
MOV DX,0
MOV DL,80H
MOV CX,1
INT 13H
MOV DX,0402H
CALL SETCURS
MOV AH,14H ; Controller Diagnostics
MOV DL,80H
INT 13H
JNC START1
LEA DX,DUFF_CONT ; Controller Faulty
CALL PRTDX
QQQ:
LEA DX,ABORT
CALL PRTDX
MOV AX,4C01H
INT 21H ; END
;==========================
START1:
PUSH CS
POP DS
CLI
CALL TIM_START ; Start the Clock
CALL TIM_STOP ; Stop the Clock
STI
MOV DX,TIM_MICRO ; Read elapsed time (overhead)
MOV ADJUSTM,DX ; Save as compensation factor
LEA DX,MESS_01 ; Show Warning Message
CALL PRTDX
CALL BACK2
LEA DI,ANSYN
CALL GETANS
CMP AL,'Y'
JZ DRSEL ; Answer was 'Y'
JMP QQQ
DRSEL:
MOV AX,40H
MOV DS,AX
MOV BX,75H ; How many H Disks?
CMP BYTE PTR [BX],2
JZ DRSEL01 ; 2 Drives so Select
MOV AL,0 ; 1 Drive so Jump
JMP SRSEL03
DRSEL01:
CALL GET_STATUS
JC DRSEL02 ; Logical Partitioning Set Up
JMP SRSEL01
DRSEL02:
LEA DX,LOG_PART
CALL PRTDX
JMP QQQ
SRSEL01:
LEA DX,SELECT1
CALL PRTDX
CALL BACK2
LEA DI,ANSCD
CALL GETANS
CMP AL,'C'
JZ SRSEL02
MOV AL,0
MOV BYTE PTR CS:[DR_ID],81H
MOV BYTE PTR CS:[MESS_OPT4],44H
JMP SRSEL03
SRSEL02:
MOV AL,20H
SRSEL03:
MOV BX,43H
MOV [BX],AL
call GET_STATUS
jnc DRREP1
mov bx,43H
cmp BYTE PTR [BX],60H
jz DRREP1
JMP DRSEL02
DRREP1:
LEA dx,DR_REPP
call PRTDX
call SET_STAT
MOV AX,800H
MOV DX,0
MOV DL,BYTE PTR CS:[DR_ID]
INT 13H ;CH=62H CL=1 0010001
INC DH
MOV CS:[HDS],DH ; Number of Heads
MOV AX,CX
MOV CX,6
SHR AL,CL
XCHG AH,AL
ADD AX,2
MOV CS:[CYLS],AX
PUSH AX
LEA DX,DR_CYL
CALL PRTDX
POP AX
CALL HEX2ASC
CALL SETBLANK
CALL SHOWNUM
LEA DX,LF
CALL PRTDX
LEA DX,DR_HDS
CALL PRTDX
SUB AX,AX
MOV AL,CS:[HDS]
CALL HEX2ASC
CALL SETBLANK
CALL SHOWNUM
CALL GETCURS
INC DH
INC DH
MOV DL,2
CALL SETCURS
LEA DX,CONFIRM
CALL PRTDX
CALL BACK2
LEA DI,ANSYN
CALL GETANS
CMP AL,'Y'
JZ FMTCMD0
JMP QQQ
FMTCMD0:
LEA DX,MESS_OPT0
CALL PRTDX
FMTCMD:
PUSH CS
POP DS
MOV CX,2 ; Two Tracks to FORMAT
FMTRAKS:
PUSH CX ; Save track count
MOV AL,CL ; Use it to mark Track
DEC AL
MOV CX,4 ; Four Heads to use
FMTRAK:
PUSH CX ; Save Head Count
PUSH AX ; Save Track indicator
MOV DH,CL ; Set Head number
DEC DH
MOV CH,AL ; CYL NO.
MOV AH,05H ; Format command
MOV AL,BYTE PTR [INTERLEAVE]
MOV BX,OFFSET DTABUF
MOV CL,1 ; SECT=1
MOV DL,BYTE PTR [DR_ID] ; Drive
INT 13H
POP AX
POP CX
LOOP FMTRAK
POP CX
LOOP FMTRAKS
;--------------------------------------------------
; Each of the following loops sets the Disk Head to a position,
; Starts the clock, resets the Disk Head and then stops the clock.
; The subsequent time is then converted and displayed.
;--------------------------------------------------
; This runs the Disk test routine 8 times and places the
; successive results in TIM1 to TIM8 Data Words
;--------------------------------------------------
IRP ?X,<1,2,3,4>
HEADSET 0,0
CLI
CALL TIM_START
HEADSET 3,310
CALL TIM_STOP
STI
CALL TIM2ASC
MOV SI,OFFSET TIM_MICRO
MOV DI,OFFSET TIM&?X&MIC
MOV CX,6
REP MOVSB
ENDM
;--------------------------------------------------
; Now we must average out the 8 test results obtained
; and put the answer back into TIM_MICRO +++
;--------------------------------------------------
SUB AX,AX ; Clear AX for addition
IRP ?X,<1,2,3,4>
ADD AX,DS:[TIM&?X&MIC]
ENDM
MOV TIM_MICRO,AX
;--------------------------------------------------
SUB AX,AX ; Clear AX for addition
IRP ?X,<1,2,3,4>
ADD AX,DS:[TIM&?X&MIL]
ENDM
MOV TIM_MILLI,AX
;--------------------------------------------------
SUB AX,AX ; Clear AX for addition
IRP ?X,<1,2,3,4>
ADD AX,DS:[TIM&?X&SEC]
ENDM
MOV DX,0
MUL THOU
ADD AX,[TIM_MILLI]
JNC NEXT1
INC DX
NEXT1:
MUL THOU
ADD AX,[TIM_MICRO]
JNC NEXT2
INC DX
NEXT2:
SHR DX,1
RCR AX,1
SHR DX,1
RCR AX,1
; Now DX:AX contains binary number of Microsecs
DIV THOU
MOV [TIM_MICRO],DX
XOR DX,DX
DIV THOU
MOV [TIM_MILLI],DX
MOV [TIM_SEC],AX
CMP [LOWSEC],AX
JC LBL2
CMP [LOWMIL],DX
JC LBL2
MOV [LOWMIL],DX
MOV [LOWSEC],AX
MOV AX,WORD PTR [INTERLEAVE]
MOV WORD PTR [INTLVE],AX
LBL2:
MOV AL,BYTE PTR [INTERLEAVE]
AAM
OR AX,3030H
XCHG AH,AL
MOV WORD PTR [MESS_EQ],AX
CALL GETCURS
PUSH DX
LEA DX,MESS_RUN ; Display Seconds Message
CALL PRTDX
CALL SHOW_AVE ; Display Average time
POP DX
CALL SETCURS
DEC BYTE PTR [INTERLEAVE]
JZ FINISH
JMP FMTCMD
FINISH:
CALL GETCURS
MOV DL,2
CALL SETCURS
LEA DX,BLANKLINE
CALL PRTDX
CALL GETCURS
MOV DL,2
CALL SETCURS
MOV AL,BYTE PTR [INTLVE]
AAM
OR AX,3030H
XCHG AH,AL
MOV WORD PTR [MESS_OPT2],AX
LEA DX,MESS_OPT1 ; Display IntLve Message
CALL PRTDX
CALL GETCURS
INC DH
MOV DL,2
CALL SETCURS
LEA DX,MESS_OPT3
CALL PRTDX
LEA DX,MESS_OPT2
CALL PRTDX
MOV AL,BYTE PTR [INTLVE]
MOV DH,0
MOV DL,BYTE PTR [DR_ID]
MOV CX,1
MOV AH,7
INT 13H ; Drive Formatted HERE
CALL GETCURS
MOV DL,2
DEC DH
CALL SETCURS
LEA DX,MESS_OPT9 ; Format Complete
CALL PRTDX
TEST:
LEA DX,MESS_OPT5 ; Bad Tracks? N Line 1
CALL PRTDX
CALL BACK2
LEA DI,ANSYN
CALL GETANS
CMP AL,'Y'
JZ BAD_TRAKS00
JMP QQQ1
BAD_TRAKS00:
CALL GETCURS
MOV DL,2
CALL SETCURS
LEA DX,MESS_OPT6 ; Enter Track Line 2
CALL PRTDX
CALL GETNUM
; TEST AX FOR VALID CYLINDER
CMP AX,WORD PTR CS:[CYLS]
JC CYLOK
CALL RINGBELL
LEA DX,BADCYL
CALL PRTDX
CALL GETCURS
DEC DH
MOV DL,2
CALL SETCURS
LEA DX,BLANKLINE
CALL PRTDX
JMP BAD_TRAKS00
CYLOK:
push ax
CYLOK1:
CALL GETCURS
INC DH
MOV DL,2
CALL SETCURS
LEA DX,MESS_OPT7 ; Enter Head Line 3
CALL PRTDX
CALL GETNUM
; TEST AX FOR VALID HEAD NUMBER
CMP AL,BYTE PTR CS:[HDS]
JC HDOK
CALL RINGBELL
LEA DX,BADHD
CALL PRTDX
CALL GETCURS
DEC DH
MOV DL,2
CALL SETCURS
LEA DX,BLANKLINE
CALL PRTDX
CALL GETCURS
DEC DH
MOV DL,2
CALL SETCURS
JMP CYLOK1
HDOK:
; AX HAS HEAD NUMBER, STACK HAS CYLINDER NUMBER
; FORMAT BAD TRACK
POP BX
CALL SET_BADTRAK
CALL GETCURS
INC DH
MOV DL,2
CALL SETCURS
LEA DX,MESS_OPT8 ; Track Flagged - MORE? Line 4
CALL PRTDX
CALL BACK2
LEA DI,ANSYN
CALL GETANS
CMP AL,'Y'
JZ BAD_TRAKS01
JMP QQQ1
BAD_TRAKS01:
CALL GETCURS
MOV DL,2
MOV CX,5
BAD_TRAKS02:
PUSH CX
CALL SETCURS
LEA DX,BLANKLINE
CALL PRTDX
CALL GETCURS
DEC DH
MOV DL,2
POP CX
LOOP BAD_TRAKS02
CALL GETCURS
MOV DL,2
CALL SETCURS
LEA DX,MESS_OPT10
CALL PRTDX
JMP BAD_TRAKS00
QQQ1:
LEA DX,CONTINUE
CALL PRTDX
; set up variables in BOOT_TRAK buffer and DX before writing Partition Table
DEC CYLS
DEC CYLS
MOV AX,[CYLS]
MOV CX,6
SHL AH,CL
OR AH,11H
XCHG AH,AL
MOV [XSECTS],AX
INC CYLS
MOV AL,44H
CBW
MUL CYLS
SUB AX,11H
MOV XSEC_END,AX
MOV AX,301H
MOV BX,OFFSET BOOT_TRAK
MOV DX,0
MOV DL,BYTE PTR [DR_ID]
MOV CX,1
INT 13H
MOV AX,40H
MOV DS,AX
INT 19H ; Terminate program and Reboot
BOOT_TRAK:
DB 0EBH,74H,90H,49H,6EH,76H,61H,6CH,69H,64H
DB 20H,70H,61H,72H,74H,69H,74H,69H,6FH,6EH
DB 20H,74H,61H,62H,6CH,65H,20H,6FH,6EH,20H
DB 66H,69H,78H,65H,64H,20H,64H,69H,73H,6BH
DB 0DH,0AH,00H,4EH,6FH,20H,6FH,70H,65H,72H
DB 61H,74H,69H,6EH,67H,20H,73H,79H,73H,74H
DB 65H,6DH,20H,6FH,6EH,20H,66H,69H,78H,65H
DB 64H,20H,64H,69H,73H,6BH,0DH,0AH,00H,45H
DB 72H,72H,6FH,72H,20H,6CH,6FH,61H,64H,69H
DB 6EH,67H,20H,73H,79H,73H,74H,65H,6DH,20H
DB 66H,72H,6FH,6DH,20H,66H,69H,78H,65H,64H
DB 20H,64H,69H,73H,6BH,0DH,0AH,00H,0FAH,0FCH
DB 33H,0C0H,8EH,0D8H,8EH,0C0H,8EH,0D0H,0BCH,00H
DB 7CH,0BEH,00H,7CH,0BFH,00H,7EH,0B9H,00H,02H
DB 0F3H,0A4H,0B8H,0E0H,07H,50H,0B8H,97H,00H,50H
DB 0CBH,0FBH,0BFH,03H,00H,0BBH,0BEH,7FH,0B9H,04H
DB 00H,2BH,0F6H,80H,3FH,00H,74H,0BH,80H,3FH
DB 80H,75H,12H,0BH,0F6H,75H,0EH,8BH,0F3H,83H
DB 0C3H,10H,0E2H,0EBH,0BFH,2BH,00H,0BH,0F6H,75H
DB 03H,0EBH,2BH,90H,8BH,14H,8BH,4CH,02H,0BBH
DB 00H,7CH,0BDH,03H,00H,0B0H,01H,0B4H,02H,0CDH
DB 13H,73H,09H,4DH,75H,0F5H,0BFH,4FH,00H,0EBH
DB 0FH,90H,0BFH,2BH,00H,81H,0BFH,0FEH,01H,55H
DB 0AAH,75H,03H,1EH,53H,0CBH,2EH,8AH,05H,47H
DB 3CH,00H,74H,09H,0BBH,07H,00H,0B4H,0EH,0CDH
DB 10H,0EBH,0EFH,0EBH,0FEH
DB 239 DUP (0)
DB 80H,01H,01H,00H,04H,03H
XSECTS DW 6291H
DB 11H,00H,00H,00H
XSEC_END DW 0A23BH
DB 00H,00H,55H,0AAH
DTABUF DW 4 DUP (?)
MAIN ENDP
CODE ENDS
END BEGIN